﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Weazel.Willows.Model
{
	public partial class SignalInConnector
		: SignalConnectorBase, ISignal, IConnector
	{
		public override void DatapathMovedDownInHierarchy(Module newParent, Module oldParent)
		{
			if (Input is Signal)
			{
				Signal signal = Input as Signal;
				
				// create a new in connector on the new parent module.
				SignalInConnector inConnector =
					new SignalInConnector(newParent, TypeRegistry, Type);
				newParent.Connectors.Add(inConnector.LocalName, inConnector);

				signal.UnbindOutput(this);
				signal.BindOutput(inConnector);

				inConnector.BindInput(signal);
				inConnector.BindOutput(this);

				UnbindInput(signal);
				BindInput(inConnector);
			}
			else 
				throw new NotImplementedException();
		}

		/// <summary>
		/// Called when the parent module of this signal is moved up in the
		/// hierarchy.
		/// </summary>
		/// <param name="newParent"></param>
		/// <param name="oldParent"></param>
		public override void DatapathMovedUpInHierarchy(Module newParent, Module oldParent)
		{
			if (Input is Signal)
			{
				Signal signal = Input as Signal;

				// Create a new out connector on the old parent module.				
				SignalOutConnector outConnector = 
					new SignalOutConnector(oldParent, TypeRegistry, Type);
				oldParent.Connectors.Add(outConnector.LocalName, outConnector);

				// Create a new signal within the new parent module.
				Signal newSignal = new Signal(newParent, TypeRegistry, Type);
				newParent.Channels.Add(newSignal.LocalName, newSignal);

				signal.UnbindOutput(this);
				signal.BindOutput(outConnector);

				outConnector.BindInput(signal);
				outConnector.BindOutput(newSignal);

				newSignal.BindInput(outConnector);
				newSignal.BindOutput(this);

				UnbindInput(signal);
				BindInput(newSignal);
			}
			else if (Input is SignalInConnector)
			{
				SignalInConnector inConnector = Input as SignalInConnector;
			}
			else
				throw new NotSupportedException();
		}

		public List<Module> GetReadingDatapaths()
		{
			return null;
		}

		private static int uniqueNameCnt = 0;
		private static string GetNextUniqueName()
		{
			return string.Format("signal_reader{0}", uniqueNameCnt++);
		}

		public SignalInConnector(Module parent, TypeRegistry typeRegistry, Type type)
			: this(parent, typeRegistry, type, GetNextUniqueName())
		{
		}

		private SignalInConnector(Module parent, TypeRegistry typeRegistry, Type type, string name)
			: base(parent, typeRegistry, type, name, name)
		{
		}

		public SignalInConnector(Module parent, TypeRegistry typeRegistry, Type type, string name, string uniqueName)
			: base(parent, typeRegistry, type, name, uniqueName)
		{
		}
	}
}
